package com.flyduck.vueshop.system.admin.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyduck.vueshop.common.core.utils.BeanUtils;
import com.flyduck.vueshop.common.core.utils.StringUtils;
import com.flyduck.vueshop.common.mybatis.utils.PageUtils;
import com.flyduck.vueshop.system.admin.service.AdminUserService;
import com.flyduck.vueshop.system.admin.vo.*;
import com.flyduck.vueshop.system.constant.SysConstant;
import com.flyduck.vueshop.system.entity.SysRole;
import com.flyduck.vueshop.system.entity.SysUser;
import com.flyduck.vueshop.system.entity.SysUserRole;
import com.flyduck.vueshop.system.manager.SysPermissionCacheManager;
import com.flyduck.vueshop.system.mapper.SysRoleMapper;
import com.flyduck.vueshop.system.mapper.SysUserMapper;
import com.flyduck.vueshop.system.mapper.SysUserRoleMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * SysUserServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-06-03
 */
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private SysPermissionCacheManager sysPermissionCacheManager;

    @Override
    public Page<AdminUserRespVO> getUserPage(Page page, AdminUserQueryReqVO adminUserQueryReqVO) {
        Page<SysUser> sysUserPage = sysUserMapper.selectPage(page,
                new LambdaQueryWrapper<SysUser>()
                        .like(StringUtils.isNotBlank(adminUserQueryReqVO.getUsername()), SysUser::getUsername, adminUserQueryReqVO.getUsername())
                        .orderByDesc(SysUser::getCreated)
        );

        Page<AdminUserRespVO> sysUserRespVOPage = PageUtils.convert(sysUserPage, AdminUserRespVO.class);
        sysUserRespVOPage.getRecords().stream().forEach(adminUserRespVO -> {
            List<SysRole> sysRoleList = sysRoleMapper.getRoleListByUserId(adminUserRespVO.getId());
            List<AdminUserRespVO.SysRoleVO> sysRoleDTOS = BeanUtils.toBeanList(sysRoleList, AdminUserRespVO.SysRoleVO.class);
            adminUserRespVO.setRoles(sysRoleDTOS);
        });

        return sysUserRespVOPage;
    }

    @Override
    public AdminUserDetailsRespVO getUserDetailsById(Long id) {
        SysUser sysUser = sysUserMapper.selectById(id);
        AdminUserDetailsRespVO adminUserDetailsRespVO = BeanUtils.toBean(sysUser, AdminUserDetailsRespVO.class);

        List<SysRole> sysRoleList = sysRoleMapper.getRoleListByUserId(id);
        List<AdminUserDetailsRespVO.SysRoleVO> sysRoleDTOS = BeanUtils.toBeanList(sysRoleList, AdminUserDetailsRespVO.SysRoleVO.class);
        adminUserDetailsRespVO.setRoles(sysRoleDTOS);

        return adminUserDetailsRespVO;
    }

    @Override
    public void saveUser(AdminUserSaveReqVO adminUserSaveReqVO) {
        SysUser sysUser = BeanUtils.toBean(adminUserSaveReqVO, SysUser.class);
        sysUser.setCreated(LocalDateTime.now());
        //默认密码
        if (StringUtils.isBlank(adminUserSaveReqVO.getPassword())) {
            sysUser.setPassword(SecureUtil.md5(SysConstant.DEFAULT_PASSWORD));
        }else {
            sysUser.setPassword(SecureUtil.md5(adminUserSaveReqVO.getPassword()));
        }
        //默认头像
        sysUser.setAvatar(SysConstant.DEFAULT_AVATAR);
        sysUserMapper.insert(sysUser);
    }

    @Override
    public void updateUser(AdminUserUpdateReqVO adminUserUpdateReqVO) {
        SysUser updateSysUser = BeanUtils.toBean(adminUserUpdateReqVO, SysUser.class);//页面的数据
        SysUser sysUser = sysUserMapper.selectById(adminUserUpdateReqVO.getId());//数据库的数据
        BeanUtils.copyProperties(updateSysUser, sysUser, "password","created","updated");//将页面的数据 设置到 数据库的数据 里面去（忽略password，created，updated）
        //页面传递密码不为空，才设置密码
        if(StringUtils.isNotBlank(adminUserUpdateReqVO.getPassword())){
            sysUser.setPassword(SecureUtil.md5(adminUserUpdateReqVO.getPassword()));
        }
        sysUser.setUpdated(LocalDateTime.now());
        sysUserMapper.updateById(sysUser);
    }

    public static void main(String[] args) {
        System.out.println(SecureUtil.md5("888888"));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchDeleteByIds(List<Long> ids) {
        //先删除用户角色管理数据
        sysUserRoleMapper.delete(
                new LambdaQueryWrapper<SysUserRole>()
                        .in(SysUserRole::getUserId,ids)
        );

        //删除用户的权限缓存
        ids.forEach(id -> {
            sysPermissionCacheManager.clearPermissionListByUserId(id);
        });

        sysUserMapper.deleteBatchIds(ids);


    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void assignRolesToUser(Long userId, List<Long> roleIds) {
        //删除之前的关系
        sysUserRoleMapper.delete(
                new LambdaQueryWrapper<SysUserRole>()
                        .eq(SysUserRole::getUserId,userId)
        );

        //建立新的关系
        List<SysUserRole> sysUserRoleList = roleIds.stream()
                .map(roleId -> {
                    SysUserRole sysUserRole = new SysUserRole();
                    sysUserRole.setUserId(userId);
                    sysUserRole.setRoleId(roleId);
                    return sysUserRole;
                }).collect(Collectors.toList());

        sysUserRoleMapper.insertBatch(sysUserRoleList);

        //删除缓存
        sysPermissionCacheManager.clearPermissionListByUserId(userId);
    }

    @Override
    public void resetPasswordById(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        sysUser.setPassword(SecureUtil.md5(SysConstant.DEFAULT_PASSWORD));
        sysUser.setUpdated(LocalDateTime.now());
        sysUserMapper.updateById(sysUser);
    }
}
